package com.xjtu.mybatisplus.service.es;

import com.xjtu.mybatisplus.model.domain.Article;
import com.xjtu.mybatisplus.model.esdocument.ESArticle;
import com.xjtu.mybatisplus.repository.ArticleRepository;
import com.xjtu.mybatisplus.service.ArticleService;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.query.FetchSourceFilter;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.elasticsearch.core.query.Query;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
public class EsArticleService {
    @Autowired
    private ArticleRepository articleRepository;

    @Autowired
    private ArticleService articleService;

    @Resource
    private ElasticsearchRestTemplate elasticsearchTemplate;

    public void saveArticle(ESArticle article) {
        articleRepository.save(article);
    }

    public void deleteArticle(String id) {
        articleRepository.deleteById(id);
    }

    public ESArticle findArticleById(String id) {
        return articleRepository.findById(id).orElse(null);
    }

    public List<Article> searchArticles(String searchTerm) {
        Query searchQuery = new NativeSearchQueryBuilder()
                .withQuery(QueryBuilders.multiMatchQuery(searchTerm, "title", "content"))
                .withHighlightFields(
                        new HighlightBuilder.Field("title").numOfFragments(1).preTags("<span class='highlight'>").postTags("</span>"),
                        new HighlightBuilder.Field("content").numOfFragments(1).preTags("<span class='highlight'>").postTags("</span>")
                )
                .withSourceFilter(new FetchSourceFilter(new String[]{}, new String[]{"content"})) // 排除 content 字段
                .build();
        return elasticsearchTemplate
                .search(searchQuery, ESArticle.class)
                .stream()
                .map(hit -> {
                    ESArticle article = hit.getContent();
                    Article result = articleService.getPublishedArticle(Long.valueOf(article.getId()));
                    if (result == null) {
                        return null;
                    }
                    if (hit.getHighlightFields().containsKey("title")) {
                        result.setTitle(hit.getHighlightFields().get("title").get(0));
                    }
                    if (hit.getHighlightFields().containsKey("content")) {
                        result.setSummary(hit.getHighlightFields().get("content").get(0));
                    }
                    return result;
                })
                .filter(Objects::nonNull)
                .collect(Collectors.toList());
    }


}
